package com.wyz.socket.test.server;

import com.wyz.socket.core.api.Close;
import com.wyz.socket.core.impl.ConnectorHandler;
import com.wyz.socket.core.utils.FileUtils;
import com.wyz.socket.core.utils.Log;

import java.io.Closeable;
import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;


public class ServerSocketListener extends Thread implements Closeable {

    public interface AcceptCallback extends Close {
        void accept(ConnectorHandler connectorHandler);
    }

    private boolean done = false;
    private Selector selector;
    private AcceptCallback callback;

    public ServerSocketListener(Selector selector, AcceptCallback callback) {
        this.selector = selector;
        this.callback = callback;
    }

    @Override
    public void run() {
        super.run();
        Selector selector = this.selector;
        Log.printlnInfo("TCP-Listener" , "服务器准备就绪～ 开始监听客户端连接......");
        // 等待客户端连接
        do {
            // 得到客户端
            try {
                if (selector.select() == 0) {
                    if (done) {
                        break;
                    }
                    continue;
                }
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()) {
                    if (done) break;
                    SelectionKey key = iterator.next();
                    iterator.remove();
                    // 检查当前Key的状态是否是我们关注的
                    // 客户端到达状态
                    if (key.isAcceptable()) {
                        ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
                        SocketChannel socketChannel = serverSocketChannel.accept();
                        // 客户端构建异步线程
                        callback.accept(new ConnectorHandler(socketChannel, FileUtils.getCacheDir("server")));
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("客户端连接异常：" + e.getMessage());
            }
        } while (!done);
        System.out.println("服务器已关闭！");
    }

    @Override
    public void close() throws IOException {
        done = true;
        // 唤醒当前的阻塞
        if (selector != null) {
            selector.wakeup();
            selector = null;
        }
        if (callback != null) {
            callback.onClose(this);
            callback = null;
        }
    }
}
